/**
 *
 */
package com.cmcc.awareness;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.CharsetDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;

import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.config.ConnectionConfig;
import org.apache.http.config.MessageConstraints;
import org.apache.http.impl.ConnSupport;
import org.apache.http.impl.DefaultHttpRequestFactory;
import org.apache.http.impl.io.DefaultHttpRequestParser;
import org.apache.http.impl.io.HttpTransportMetricsImpl;
import org.apache.http.impl.io.SessionInputBufferImpl;
import org.apache.http.message.BasicLineParser;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

/**
 * @Date 2018年4月4日 下午12:03:07
 * @author Amish
 * (1)解析http.proto
 * (2)提供业务识别入口方法和实现
 * (3)已经[支持]的HTTP类的字段：Uri，Content-Type，Host，x-online-host，Referer，User-Agent，Pragma，X-Requested-With，
 * c_version，X-Umeng-Sdk，Client-Agent，appname，DPUName，actionlocation，Cookie，Q-UA, X-Session-Type, Server
 * 
 * (4)HTTP附属标记字段
 *   1、[不支持]Data：
 *   2、[支持]Priority：20180502  已经支持HTTP附属标记字段priority：取值为0、1、2。0为最高优先级，依次降低，不写此项则默认优先级为0。
 * 
 * 
 * (5)持其他功能字段：
 *   1.[不支持]Dnsquery、。（http.proto中暂未出现）
 *   2.[支持]HTTPS类识别字段（Tls_server、id-at-commonName）、。
 *   3.[不支持]Http_server、。（http.proto中暂未出现）
 *   4.[不支持]suffix、。（http.proto中暂未出现）
 *   5.[不支持]DSCP、。（http.proto中暂未出现）
 *   6.[不支持]Tcpdata、。（http.proto中暂未出现）
 *   7.[不支持]Udpdata、。（http.proto中暂未出现）
 *   8.[不支持]RTMP协议特征识别字段（Swfurl、Tcurl、Pageurl）、。（http.proto中暂未出现）
 * 
 * (6)http 和 https 使用的是完全不同的连接方式，用的端口也不一样，前者是 80，后者是 443。
 * (7)对于0x+十六进制字符串的值，处理时直接取0x后面的部分当字符串处理即可
 * (8)对于%..的字符串的值，直接取整个部分当字符串处理即可
 * 
 */
public class HttpProto {
	private static Logger logger = LogManager.getLogger(HttpProto.class);
	
	public HashMap<String,HttpProtoApp> httpProtoApps_priority0;//存放pPriority为0的所有rules，按照HttpProtoApp归类
	public HashMap<String,HttpProtoApp> httpProtoApps_priority1;//存放pPriority为1的所有rules，按照HttpProtoApp归类
	public HashMap<String,HttpProtoApp> httpProtoApps_priority2;//存放pPriority为2的所有rules，按照HttpProtoApp归类
	
//	public static HttpProto httpProto = new HttpProto();
//	public static HttpProto getInstance(){//饿汉...
//		return httpProto;
//	}


	public HttpProto(String httpProtoPath){
		httpProtoApps_priority0 = new HashMap<String,HttpProtoApp>();
		httpProtoApps_priority1 = new HashMap<String,HttpProtoApp>();
		httpProtoApps_priority2 = new HashMap<String,HttpProtoApp>();
		this.parseFile(httpProtoPath);
	}
			
	
	/**
	 * 传入解析后HttpRequest进行业务识别
	 * 优先匹配priority=0的rule，然后是1和2
	 * 同一priority内，按照先后顺序，匹配到了直接返回
	 * @param httpRequest (from httpcore4.4.9)
	 * @return
	 */
    /*public AppInfo appDistinguish(org.apache.http.HttpRequest httpRequest){
		//priority=0的规则识别
    	for(Entry<String, HttpProtoApp> entry : httpProtoApps_priority0.entrySet()){
    		HttpProtoApp httpProtoApp = entry.getValue();
    		String matchAppName = httpProtoApp.distinguish(httpRequest);
    		if(matchAppName != null){
    			return ProtoList.getInstance().appInfos.get(matchAppName);
    		}
    	}
    	//priority=1的规则识别
    	for(Entry<String, HttpProtoApp> entry : httpProtoApps_priority1.entrySet()){
    		HttpProtoApp httpProtoApp = entry.getValue();
    		String matchAppName = httpProtoApp.distinguish(httpRequest);
    		if(matchAppName != null){
    			return ProtoList.getInstance().appInfos.get(matchAppName);
    		}
    	}
    	//priority=2的规则识别
    	for(Entry<String, HttpProtoApp> entry : httpProtoApps_priority2.entrySet()){
    		HttpProtoApp httpProtoApp = entry.getValue();
    		String matchAppName = httpProtoApp.distinguish(httpRequest);
    		if(matchAppName != null){
    			return ProtoList.getInstance().appInfos.get(matchAppName);
    		}
    	}
		return null;
	}*/


	public AppInfo appDistinguish(org.apache.http.HttpRequest httpRequest,String protoListPath){
		ProtoList protoList = new ProtoList(protoListPath);
		//priority=0的规则识别
		for(Entry<String, HttpProtoApp> entry : httpProtoApps_priority0.entrySet()){
			HttpProtoApp httpProtoApp = entry.getValue();
			String matchAppName = httpProtoApp.distinguish(httpRequest);
			if(matchAppName != null){
				return protoList.appInfos.get(matchAppName);
			}
		}
		//priority=1的规则识别
		for(Entry<String, HttpProtoApp> entry : httpProtoApps_priority1.entrySet()){
			HttpProtoApp httpProtoApp = entry.getValue();
			String matchAppName = httpProtoApp.distinguish(httpRequest);
			if(matchAppName != null){
				return protoList.appInfos.get(matchAppName);
			}
		}
		//priority=2的规则识别
		for(Entry<String, HttpProtoApp> entry : httpProtoApps_priority2.entrySet()){
			HttpProtoApp httpProtoApp = entry.getValue();
			String matchAppName = httpProtoApp.distinguish(httpRequest);
			if(matchAppName != null){
				return protoList.appInfos.get(matchAppName);
			}
		}
		return null;
	}
	
	public Map<String,Object> appDistinguishWithRule(org.apache.http.HttpRequest httpRequest,String protoListPath){
		ProtoList protoList = new ProtoList(protoListPath);
		Map<String,Object> result = new HashMap<>();
		//priority=0的规则识别
		for(Entry<String, HttpProtoApp> entry : httpProtoApps_priority0.entrySet()){
			HttpProtoApp httpProtoApp = entry.getValue();
			HttpProtoRule httpProtoRule = httpProtoApp.distinguishWithRule(httpRequest);
			if(httpProtoRule != null){
				result.put("appInfo",protoList.appInfos.get(httpProtoApp.appName));
				result.put("rule",httpProtoRule);
				return result;
			}
		}
		//priority=1的规则识别
		for(Entry<String, HttpProtoApp> entry : httpProtoApps_priority1.entrySet()){
			HttpProtoApp httpProtoApp = entry.getValue();
			HttpProtoRule httpProtoRule = httpProtoApp.distinguishWithRule(httpRequest);
			if(httpProtoRule != null){
				result.put("appInfo",protoList.appInfos.get(httpProtoApp.appName));
				result.put("rule",httpProtoRule);
				return result;
			}
		}
		//priority=2的规则识别
		for(Entry<String, HttpProtoApp> entry : httpProtoApps_priority2.entrySet()){
			HttpProtoApp httpProtoApp = entry.getValue();
			HttpProtoRule httpProtoRule = httpProtoApp.distinguishWithRule(httpRequest);
			if(httpProtoRule != null){
				result.put("appInfo",protoList.appInfos.get(httpProtoApp.appName));
				result.put("rule",httpProtoRule);
				return result;
			}
		}
		return result;
	}

    /**
     * 传入HTTP消息对应的byte[]数组进行业务识别
     * @param httpByte
     * @return
     */
    public AppInfo appDistinguish(byte[] httpByte,String protoListPath){
        ByteArrayInputStream inputStream = new ByteArrayInputStream(httpByte);//模拟ServerSocket.getInputStream
		
		CharsetDecoder chardecoder = ConnSupport.createDecoder(ConnectionConfig.DEFAULT);
		HttpTransportMetricsImpl inTransportMetrics = new HttpTransportMetricsImpl();
		/**
		 * SessionInputBufferImpl
		 */
		int buffersize = httpByte.length;
		
		SessionInputBufferImpl inbuffer = new SessionInputBufferImpl(inTransportMetrics, buffersize, -1,MessageConstraints.DEFAULT, chardecoder);
		inbuffer.bind(inputStream);
		
		/**
		 * DefaultHttpRequestParser
		 */
		DefaultHttpRequestParser defaultHttpRequestParser = new DefaultHttpRequestParser(inbuffer, BasicLineParser.INSTANCE, DefaultHttpRequestFactory.INSTANCE, MessageConstraints.DEFAULT);
		
		HttpRequest httpRequest = null;
		try {
			httpRequest = defaultHttpRequestParser.parse();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (HttpException e) {
			e.printStackTrace();
		}
		if(httpRequest !=null) {
			return this.appDistinguish(httpRequest,protoListPath);
		}else {
			return null;
		}
			
    }
    
    /**
     * 用户HTTPS的业务识别，只需要支持Tls_server和id-at-commonName
     * 
     * TODO 如果后续继续支持DNS等，改方法考虑传一个HaspMap作为参数。或者针对HTTPS，DNS分别
     * 有对应的方法，这些方法统一构造出HaspMap再向底层传递
     * 
     * @param https_Tls_server
     * @param https_id_at_commonName
     * @return
     */
    public AppInfo appDistinguish(String https_Tls_server , String https_id_at_commonName,String protoListPath){
		ProtoList protoList = new ProtoList(protoListPath);

    	if("".equals(https_Tls_server) && "".equals(https_id_at_commonName) && https_Tls_server== null && https_id_at_commonName == null){
    		return null;
    	}
    	
    	//priority=0的规则识别
    	for(Entry<String, HttpProtoApp> entry : httpProtoApps_priority0.entrySet()){
    		HttpProtoApp httpProtoApp = entry.getValue();
    		String matchAppName = httpProtoApp.distinguish(https_Tls_server , https_id_at_commonName);
    		if(matchAppName != null){
    			return protoList.appInfos.get(matchAppName);
    		}
    	}
    	//priority=1的规则识别
    	for(Entry<String, HttpProtoApp> entry : httpProtoApps_priority1.entrySet()){
    		HttpProtoApp httpProtoApp = entry.getValue();
    		String matchAppName = httpProtoApp.distinguish(https_Tls_server , https_id_at_commonName);
    		if(matchAppName != null){
    			return protoList.appInfos.get(matchAppName);
    		}
    	}
    	//priority=2的规则识别
    	for(Entry<String, HttpProtoApp> entry : httpProtoApps_priority2.entrySet()){
    		HttpProtoApp httpProtoApp = entry.getValue();
    		String matchAppName = httpProtoApp.distinguish(https_Tls_server , https_id_at_commonName);
    		if(matchAppName != null){
    			return protoList.appInfos.get(matchAppName);
    		}
    	}
		return null;
    }
    
    /**
     * 用户HTTPS的业务识别，只需要支持Tls_server和id-at-commonName
     * 
     * TODO 如果后续继续支持DNS等，改方法考虑传一个HaspMap作为参数。或者针对HTTPS，DNS分别
     * 有对应的方法，这些方法统一构造出HaspMap再向底层传递
     * 
     * @param https_Tls_server
     * @param https_id_at_commonName
     * @return
     */
    public Map<String,Object> appDistinguishWithRule(String https_Tls_server , String https_id_at_commonName,String protoListPath){
		ProtoList protoList = new ProtoList(protoListPath);
		Map<String,Object> result = new HashMap<>();

    	if("".equals(https_Tls_server) && "".equals(https_id_at_commonName) && https_Tls_server== null && https_id_at_commonName == null){
    		return result;
    	}
    	
    	//priority=0的规则识别
    	for(Entry<String, HttpProtoApp> entry : httpProtoApps_priority0.entrySet()){
    		HttpProtoApp httpProtoApp = entry.getValue();
    		HttpProtoRule httpProtoRule = httpProtoApp.distinguishWithRule(https_Tls_server , https_id_at_commonName);
    		if(httpProtoRule != null){
				result.put("appInfo",protoList.appInfos.get(httpProtoApp.appName));
				result.put("rule",httpProtoRule);
				return result;
    		}
    	}
    	//priority=1的规则识别
    	for(Entry<String, HttpProtoApp> entry : httpProtoApps_priority1.entrySet()){
    		HttpProtoApp httpProtoApp = entry.getValue();
    		HttpProtoRule httpProtoRule = httpProtoApp.distinguishWithRule(https_Tls_server , https_id_at_commonName);
    		if(httpProtoRule != null){
				result.put("appInfo",protoList.appInfos.get(httpProtoApp.appName));
				result.put("rule",httpProtoRule);
				return result;
    		}
    	}
    	//priority=2的规则识别
    	for(Entry<String, HttpProtoApp> entry : httpProtoApps_priority2.entrySet()){
    		HttpProtoApp httpProtoApp = entry.getValue();
    		HttpProtoRule httpProtoRule = httpProtoApp.distinguishWithRule(https_Tls_server , https_id_at_commonName);
    		if(httpProtoRule != null){
				result.put("appInfo",protoList.appInfos.get(httpProtoApp.appName));
				result.put("rule",httpProtoRule);
				return result;
    		}
    	}
		return result;
    }
    
    private void parseFile(String httpProtoPath){
//    	String path = ProtoList.class.getResource("/").getPath()+"config/http.proto";
		httpProtoPath = httpProtoPath.replace("%20", " ");
		httpProtoPath = httpProtoPath.replace("%23", "#");
//    	
//    	File file = new File(path);
		Scanner sc = null;

		try {
			PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
//			Resource[] resources = resolver.getResources("classpath*:*config/http.proto");
			Resource[] resources = resolver.getResources("file:"+httpProtoPath);
			if(resources!=null||resources.length!=0) {
				sc = new Scanner(resources[0].getInputStream());
				String str = null;
				ArrayList<String> alTemp = new ArrayList<String>();
				while (sc.hasNextLine()) {
					str = sc.nextLine().trim();
					if(!str.equalsIgnoreCase("")){
						alTemp.add(str);
					}else{
						this.parseHttpProtoRule(alTemp);					
						alTemp.clear();//遇到空行，清空List
					}				
				}
			}
		} catch (Exception e) {
			logger.error(e.getCause(),e);
		} finally {
			sc.close();
		}
    }
    
    private void parseHttpProtoRule(ArrayList<String> al){
    	if(al.size() == 0)
    		return;
    	
    	String rule_id = null;
    	String rule_priority = "0";//默认优先级0
    	String app_subtype_name = null;
    	ArrayList<HttpProtoRuleField> ruleFields = new ArrayList<HttpProtoRuleField>();
    	
    	for(String str : al){
    		if(str.startsWith("[")){ 			
    		    //donothing
    		}else if(str.startsWith("#Rule_ID:")){
    			rule_id = str.substring(str.indexOf(":")+1);
    		}else if(str.startsWith("#")){
    			//donothing
    		}else if(str.startsWith("name=")){
    			app_subtype_name = str.substring(str.indexOf("=")+1);
    		}else if(str.startsWith("priority=") || str.startsWith("Priority=")) {
    			rule_priority = str.substring(str.indexOf("=")+1);
    		}else{
    			int equals_sign = str.indexOf("=");
    			String field = str.substring(0, equals_sign);
    			String ruleStr = str.substring(equals_sign+1);
    			HttpProtoRuleField httpProtoRuleField = new HttpProtoRuleField();
    			httpProtoRuleField.setField(field);
    			httpProtoRuleField.setRuleStr(ruleStr);
    			ruleFields.add(httpProtoRuleField);
    		}
    	}
    	
    	if(app_subtype_name == null || ruleFields.size()==0)
    		return;
    		
    	HttpProtoRule httpProtoRule = new HttpProtoRule();
    	httpProtoRule.appName = app_subtype_name;
    	httpProtoRule.rule_id = rule_id;
    	httpProtoRule.priority = rule_priority;
    	if(ruleFields.size()>1){
    		httpProtoRule.ruleFields = (ArrayList<HttpProtoRuleField>) ruleFields.clone();
    	}else{
    		httpProtoRule.httpProtoRuleField = ruleFields.get(0);
    	}
    	
    	HashMap<String,HttpProtoApp> httpProtoApps = null;
    	switch(httpProtoRule.priority) {
    	
    	case "0":
    		httpProtoApps = httpProtoApps_priority0;
    		break;
    	case "1":
    		httpProtoApps = httpProtoApps_priority1;
    		break;
    	case "2":
    		httpProtoApps = httpProtoApps_priority2;
    		break;
    	default :
    		logger.error("http.proto 's  rule wiht priority < "+httpProtoRule.priority+" > is not support");
    		break;
    	}
    	
    	if(httpProtoApps == null)
            return;
    	
    	HttpProtoApp httpProtoApp = null;
    	if(httpProtoApps.containsKey(app_subtype_name)){
    		httpProtoApp = httpProtoApps.get(app_subtype_name);
    		//System.out.println("contain");
    	}else{
    		httpProtoApp = new HttpProtoApp();
    		httpProtoApp.appName = app_subtype_name;
    		httpProtoApps.put(app_subtype_name, httpProtoApp);
    		//System.out.println("not contain");
    	}
    	httpProtoApp.rules.add(httpProtoRule);
    	
    	
    }
    
    public static int getHttpProtoRuleInfoFile(HashMap<String,HashMap<String,Integer>> httpProtoRuleInfo) {
    	String path = "E:\\AI&5G\\httpProtoRuleInfo.csv";
    	path = path.replace("%20", " ");
    	path = path.replace("%23", "#");
    	
    	File file = new File(path);
 
        try {
        	if(!file.exists()){
            	file.createNewFile();
            }
        	
        	FileWriter fileWritter = new FileWriter(file,true);
            for(Entry<String, HashMap<String,Integer>> app_rule_info : httpProtoRuleInfo.entrySet()) {
            	fileWritter.write(app_rule_info.getKey()+":\n");
            	StringBuffer sb1=new StringBuffer();
            	StringBuffer sb2=new StringBuffer();
            	for(Entry<String, Integer> sub_type_rule_info : app_rule_info.getValue().entrySet()) {
            		sb1.append("|").append(sub_type_rule_info.getKey());
            		sb2.append("|").append(sub_type_rule_info.getValue());   
            		System.out.println(sub_type_rule_info.getKey()+"-----------"+sub_type_rule_info.getValue());
            	}
            	fileWritter.write(sb1+"\n");
            	fileWritter.write(sb2+"\n");
        	}
    		fileWritter.close();
        }catch(IOException e){
        	e.printStackTrace();
//        	logger.info(e);
        	System.out.print(e);
        }
        		
	    int appSubNum=0;
    	for(Entry<String, HashMap<String,Integer>> app_sub_type : httpProtoRuleInfo.entrySet()) {
    		appSubNum += app_sub_type.getValue().size();
    	}
    	return appSubNum;
    }
    
    
    /** 
     * only for test
     * @param args
     */
    public static void main(String args[]){

    	HttpProto hp = new HttpProto("D:\\workspace\\cmcc-common\\cmcc-common-awareness\\src\\main\\resources\\config\\http.proto");
    	HashMap<String,HashMap<String,Integer>> httpProtoRuleInfo = new HashMap<String,HashMap<String,Integer>>();

		String protoList = "D:\\workspace\\cmcc-common\\cmcc-common-awareness\\src\\main\\resources\\config\\proto.list";
    	
    	String appNum=new String();
    	for(Entry<String, HttpProtoApp> entry : hp.httpProtoApps_priority0.entrySet()){
    		
    		StringBuilder sb = new StringBuilder();
    		sb.append("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
    		String appName = entry.getKey();
    		sb.append("name="+appName+"\n");    		
    		HttpProtoApp httpProtoApp = entry.getValue();
    		
    		HashMap<String,AppInfo> appInfos = new ProtoList(protoList).appInfos;
    		if(appInfos.containsKey(appName)) {
    			appNum = appInfos.get(appName).app_num.substring(0, 2);
//    			System.out.println(appNum+"-------------"+appName+"------------------"+httpProtoApp.rules.size());
    			if(httpProtoRuleInfo.containsKey(appNum)){
            		httpProtoRuleInfo.get(appNum).put(appName, httpProtoApp.rules.size());
            	}else {
            		HashMap<String,Integer> hpri = new HashMap<String,Integer>();
            		hpri.put(appName, httpProtoApp.rules.size());
            		httpProtoRuleInfo.put(appNum,hpri);
            	}
    		}else {
    			System.out.print("未找到"+appName+"对应编码\n");
    		}
        	   		
    		for(HttpProtoRule hpr : httpProtoApp.rules){
    			sb.append("#Rule_id="+hpr.rule_id+"\n");
    			if(hpr.httpProtoRuleField!=null){
    				HttpProtoRuleField hprf = hpr.httpProtoRuleField;
    				sb.append(hprf.getField()+"="+hprf.getRuleStr()+" ruleRegex: <"+hprf.getRuleStrRegex()+" >"+"\n");
    			}else{
    				for(HttpProtoRuleField hprf : hpr.ruleFields){
    					sb.append(hprf.getField()+"="+hprf.getRuleStr()+" ruleRegex: <"+hprf.getRuleStrRegex()+" >"+"\n");
    				}
    			}
    			
    		}
    		
    		logger.info(sb.toString());
//    		System.out.println(sb.toString());
    	}
    	
    	for(Entry<String, HttpProtoApp> entry : hp.httpProtoApps_priority1.entrySet()){
    		
    		StringBuilder sb = new StringBuilder();
    		sb.append("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
    		String appName = entry.getKey();
    		sb.append("name="+appName+"\n");
    		HttpProtoApp httpProtoApp = entry.getValue();
    		
    		HashMap<String,AppInfo> appInfos = new ProtoList(protoList).appInfos;
    		if(appInfos.containsKey(appName)) {
    			appNum = appInfos.get(appName).app_num.substring(0, 2);
    			if(httpProtoRuleInfo.containsKey(appNum)) {
    				if(httpProtoRuleInfo.get(appNum).containsKey(appName)){
    					httpProtoRuleInfo.get(appNum).put(appName, httpProtoRuleInfo.get(appNum).get(appName)+httpProtoApp.rules.size());
    				}else {
    					httpProtoRuleInfo.get(appNum).put(appName, httpProtoApp.rules.size());
    				}
            	}else {
            		HashMap<String,Integer> hpri = new HashMap<String,Integer>();
            		hpri.put(appName, httpProtoApp.rules.size());
            		httpProtoRuleInfo.put(appNum,hpri);
            	}
    		}else {
    			System.out.print("未找到"+appName+"对应编码\n");
    		}
    		
    		for(HttpProtoRule hpr : httpProtoApp.rules){
    			sb.append("#Rule_id="+hpr.rule_id+"\n");
    			if(hpr.httpProtoRuleField!=null){
    				HttpProtoRuleField hprf = hpr.httpProtoRuleField;
    				sb.append(hprf.getField()+"="+hprf.getRuleStr()+" ruleRegex: <"+hprf.getRuleStrRegex()+" >"+"\n");
    			}else{
    				for(HttpProtoRuleField hprf : hpr.ruleFields){
    					sb.append(hprf.getField()+"="+hprf.getRuleStr()+" ruleRegex: <"+hprf.getRuleStrRegex()+" >"+"\n");
    				}
    			}
    			
    		}
    		logger.info(sb.toString());
    	}

		for(Entry<String, HttpProtoApp> entry : hp.httpProtoApps_priority2.entrySet()){
			
			StringBuilder sb = new StringBuilder();
			sb.append("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
			String appName = entry.getKey();
			sb.append("name="+appName+"\n");
			HttpProtoApp httpProtoApp = entry.getValue();
			
			HashMap<String,AppInfo> appInfos = new ProtoList(protoList).appInfos;
    		if(appInfos.containsKey(appName)) {
    			appNum = appInfos.get(appName).app_num.substring(0, 2);
    			if(httpProtoRuleInfo.containsKey(appNum)) {
    				if(httpProtoRuleInfo.get(appNum).containsKey(appName)){
    					httpProtoRuleInfo.get(appNum).put(appName, httpProtoRuleInfo.get(appNum).get(appName)+httpProtoApp.rules.size());
    				}else {
    					httpProtoRuleInfo.get(appNum).put(appName, httpProtoApp.rules.size());
    				}
            	}else {
            		HashMap<String,Integer> hpri = new HashMap<String,Integer>();
            		hpri.put(appName, httpProtoApp.rules.size());     
            		httpProtoRuleInfo.put(appNum,hpri);
            	}
    		}else {
    			System.out.print("未找到"+appName+"对应编码\n");
    		}
    		
			
			for(HttpProtoRule hpr : httpProtoApp.rules){
				sb.append("#Rule_id="+hpr.rule_id+"\n");
				if(hpr.httpProtoRuleField!=null){
					HttpProtoRuleField hprf = hpr.httpProtoRuleField;
					sb.append(hprf.getField()+"="+hprf.getRuleStr()+" ruleRegex: <"+hprf.getRuleStrRegex()+" >"+"\n");
				}else{
					for(HttpProtoRuleField hprf : hpr.ruleFields){
						sb.append(hprf.getField()+"="+hprf.getRuleStr()+" ruleRegex: <"+hprf.getRuleStrRegex()+" >"+"\n");
					}
				}
				
			}
//			logger.info(sb.toString());
		}
		System.out.println(httpProtoRuleInfo.toString());
		int appSubNum = getHttpProtoRuleInfoFile(httpProtoRuleInfo);
    	System.out.println("共解析对应到proto.list业务大类个数："+httpProtoRuleInfo.size()+",业务小类个数"+appSubNum);
	    
		logger.info("httpProtoApps_priority0 size : "+hp.httpProtoApps_priority0.size());
		logger.info("httpProtoApps_priority1 size : "+hp.httpProtoApps_priority1.size());
		logger.info("httpProtoApps_priority2 size : "+hp.httpProtoApps_priority2.size());
		
		logger.info("https distinguish : "+hp.appDistinguish(".skype", "",protoList));
		logger.info("https distinguish : "+hp.appDistinguish("baidu.com", "",protoList));
		logger.info("https distinguish : "+hp.appDistinguish("pan.baidu.com", "",protoList));
		logger.info("https distinguish : "+hp.appDistinguish("", "",protoList));
		logger.info("https distinguish : "+hp.appDistinguish("xxx", "",protoList));
    }
    
}